
package de.dtools.n2g.note;

/**
 *	@project:	note2go
 *	@author:	D.Toepel
 *	@version:	2009-08-04
 *	@note:		---
 *	
 *	Copyright (C) 2009  D.Toepel <de.dtools> {at} <gmail> {dot} <com>
 *	
 *	This program is free software: you can redistribute it and/or modify
 *	it under the terms of the GNU General Public License as published by
 *	the Free Software Foundation, either version 3 of the License, or
 *	(at your option) any later version.
 *	
 *	This program is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *	GNU General Public License for more details.
 *	
 *	You should have received a copy of the GNU General Public License
 *	along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *	
 */

import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.*;
import java.net.URISyntaxException;
import java.nio.channels.FileChannel;

import java.text.AttributedCharacterIterator.Attribute;
import java.util.*;

import javax.swing.*;
import javax.swing.event.*;
import javax.swing.filechooser.*;
import javax.swing.filechooser.FileFilter;
import javax.swing.plaf.FileChooserUI;
import javax.swing.plaf.basic.BasicFileChooserUI;
import javax.swing.text.*;
import javax.swing.text.html.*;
import javax.swing.text.rtf.RTFEditorKit;
import javax.swing.undo.*;

import javax.swing.text.rtf.*;

import com.Ostermiller.Syntax.HighlightedDocument;

import de.dtools.n2g.res.Resource;

/**
 * Erzeugen des Editorpanels
 * 
 * @author daniel
 */
public class Editor extends JPanel{
	
//	{
//		try {
//			UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
//		} catch(Exception e) {
//			// Nothing
//		}
//	}

	private static final long serialVersionUID = 1L;
	
    //undo helpers
    protected UndoAction undoAction;
    protected RedoAction redoAction;
    protected UndoManager undo = new UndoManager();

	private JPanel textHolder1;
	private JPanel textHolder2;
	private JScrollPane sp;
	
    private JTextPane tp;
    private Document rtfDoc;
    private Document htmlDoc;
    private RTFEditorKit rtfKit;
    private HTMLEditorKit htmlKit;
    
	private HighlightedDocument document; 
	private JTextPane textPane;
	
	private JTextPane textHelp;
	
	private TextTransformer tt = new TextTransformer();
    private HashMap<Object, Action> actions;
    private JPopupMenu popup;
    private JMenuItem menuItem;
    private JMenu submenu;
    
    private JTextArea srcTA;
    
    private String plainText;
    private String newline = "\n";
    
    protected static Integer TAB_SIZE = 4;
    
    private static Resource res = new Resource();
    
	
	
	public Editor () {
      super ();
      initGUI();
      rtfDoc.addUndoableEditListener(new MyUndoableEditListener());
	}
	
	private void initGUI(){
		try {
			{
				StyleContext sc = new StyleContext();
				rtfDoc = new DefaultStyledDocument(sc);
				rtfDoc.putProperty("tabSize",4);
				rtfKit = new RTFEditorKit();
//				rtfDoc = rtfKit.createDefaultDocument();
				
				htmlKit = new HTMLEditorKit();
				htmlDoc = htmlKit.createDefaultDocument();
				
				tp = new JTextPane();
				tp.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
				tp.setEditorKit(rtfKit);
				tp.setContentType("text/rtf");//rtf
				tp.setDocument(rtfDoc);//rtfDoc
				tp.addMouseListener(new PopupListener());
			    tp.addKeyListener(getEditorKeyListener());
			    tp.setBackground(new java.awt.Color(255,255,255));
			    tp.putClientProperty("tabSize",4);
			    
				textHolder1 = new JPanel(new BorderLayout());
				textHolder1.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
				textHolder1.add(tp, BorderLayout.CENTER);
				
			    createPopUp(tp);
			    setTabs(tp, 4);
			}
			{
				document = new HighlightedDocument(); 
				document.setHighlightStyle(HighlightedDocument.HTML_KEY_STYLE);
				
				textPane = new JTextPane(document);
				textPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
				
				textHolder2 = new JPanel(new BorderLayout());
				textHolder2.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
				textHolder2.add(textPane, BorderLayout.CENTER);
			}
			{
				sp = new JScrollPane(textHolder1);
				sp.getHorizontalScrollBar().setUnitIncrement(30);
				sp.getVerticalScrollBar().setUnitIncrement(30);
				sp.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
			}
			{
				Color c = this.getBackground();
				
				textHelp = new JTextPane();
				textHelp.setContentType("text/html");
				textHelp.setBorder(BorderFactory.createEmptyBorder(0,0,0,0));
				textHelp.setText(
						"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">" +
		       			"<html xmlns=\"http://www.w3.org/1999/xhtml\"><head>" +
		       			"<style type=\"text/css\">" +
		       			"body { height: 100%;width: 100%;margin: 0px 5px;padding: 0;background-color:" +
		       			"rgb("+ c.getRed() + ","+ c.getGreen() + ","+ c.getBlue() + ");}" +
		       			"h4{color:#1818A5;font-size:105%;margin-top:5px;margin-bottom:2px;font-weight:normal;}" +
		       			"</style></head><body>" +
		       			"<b>Hinweis zum Dateityp:</b><br>" +
		       			"<h4>*.jar - Java Styled Document</h4>" +
		       			"Dieses Format enthaelt saemtlich Informationen <br>" +
		       			"der Notiz (Text, Bilder, etc.).<br>" +
		       			"Ausserdem ist ein Betrachter integriert, <br>" +
		       			"um die Notiz auch ohne Note2Go zu lesen." +
		       			"<h4>*.zip - Java Styled Document</h4>" +
		       			"Dieses Format enthaelt saemtlich Informationen <br>" +
		       			"der Notiz (Text, Bilder, etc.).<br>" +
		       			"<h4>*.rtf - Rich Text Format</h4>" +
		       			"Dieses Format enthaelt lediglich die <br>" +
		       			"Textinformationen. Es kann jedoch mit einem <br>" +
		       			"Textverarbeitungsprogramm geoeffnet und <br>" +
		       			"bearbeitet werden. <br>" +
//		       			"<h4>\"Zusatzinformationen\"</h4>" +
//		       			"Wichtige Informationen zu dieser Notiz <br>" +
//		       			"werden in einer XML-Datei gespeichert. <br>" +
//		       			"Wird diese Notiz wieder importiert, stehen <br>" +
//		       			"alle Daten wieder zur Verfuegung." +
						"</body></html>");
				textHelp.setEditable(false);
			}
//			{
//				try {
//					UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
//					SwingUtilities.updateComponentTreeUI(tp);
//					tp.setUI(new javax.swing.plaf.metal MetalTextUI() );
//				} catch(Exception e) {
//					// Nothing
//				}
//
//			}
			
			this.setLayout(new BorderLayout());
			this.add(getToolBar(), BorderLayout.PAGE_START);
			this.add(sp, BorderLayout.CENTER);
			
		} catch (Exception e) {}
	}
	
	
	// ***************************************
	// *** EVENT HANDLER *********************
	// ***************************************
	
	protected javax.swing.event.EventListenerList listenerList =
        new javax.swing.event.EventListenerList();

	
	// This methods allows classes to register for EntryEvents
    public void addEditorEventListener(EntryEvents listener) {
        listenerList.add(EntryEvents.class, listener);
    }

    // This methods allows classes to unregister for EntryEvents
    public void removeEditorEventListener(EntryEvents listener) {
        listenerList.remove(EntryEvents.class, listener);
    }

    // This private class is used to fire ButtonOptions
    void fireButtonOptions(ActionEvent evt) {
        Object[] listeners = listenerList.getListenerList();
        for (int i=0; i<listeners.length; i+=2) {
            if (listeners[i]==EntryEvents.class) {
                ((EntryEvents)listeners[i+1]).buttonOptions_Clicked(evt);
            }
        }
    }

    // This private class is used to fire ButtonSave
    void fireButtonSave(ActionEvent evt) {
        Object[] listeners = listenerList.getListenerList();
        for (int i=0; i<listeners.length; i+=2) {
            if (listeners[i]==EntryEvents.class) {
                ((EntryEvents)listeners[i+1]).buttonSave_Clicked(evt);
            }
        }
    }

    // This private class is used to fire ButtonDelete
    void fireButtonDelete(ActionEvent evt) {
        Object[] listeners = listenerList.getListenerList();
        for (int i=0; i<listeners.length; i+=2) {
            if (listeners[i]==EntryEvents.class) {
                ((EntryEvents)listeners[i+1]).buttonDelete_Clicked(evt);
            }
        }
    }


    // This private class is used to fire ButtonRefresh
    void fireButtonRefresh(ActionEvent evt) {
        Object[] listeners = listenerList.getListenerList();
        for (int i=0; i<listeners.length; i+=2) {
            if (listeners[i]==EntryEvents.class) {
                ((EntryEvents)listeners[i+1]).buttonRefresh_Clicked(evt);
            }
        }
    }

    // ***************************************
	// *** GETTERS AND SETTERS ***************
	// ***************************************
    

    public void setTabSize(int tabSize){
//    	Editor.TAB_SIZE = tabSize;
    }
    
    public void setStyleType(String styleType){
//    	tp.setContentType(styleType);

//    	String[] style = styleType.split("/");
//		if(style[0].matches("code")){
//			tp.setFont(new java.awt.Font("Courier New",0,14));
//			setToolBarEnabled(false);
//			System.out.println(style[0] + " <:c:> " + style[1]);
//		}
//		else if (style[0].matches("text") && style[1].matches("plain")){
//			tp.setFont(new java.awt.Font("Verdana",0,12));
//			tp.setForeground(new java.awt.Color(0,0,0));
//			setToolBarEnabled(false);
//			System.out.println(style[0] + " <:p:> " + style[1]);
//		}
//		else{
//			setToolBarEnabled(true);
//			System.out.println(style[0] + " <:n:> " + style[1] + "-->" + style.length);
//		}
		
    }
    
    public void setContent(String content){
	    tp.setText(content);
	    validate();
    }
//    
//    public void setContent(Document content){
//	    tp.setDocument(content);
//	    validate();
//    }
//    
//    public void setContent(StyledDocument content){
// 	    tp.setStyledDocument(content);
//	    validate();
//    }
//    
    public String getPlainText(){
    	String out = "";
    	try {
			out = tp.getDocument().getText(0, tp.getDocument().getLength());
		} catch (BadLocationException e) {
			out = e.toString();
		}
		return out;
    }
    
    public String getHtmlText(){
    	ByteArrayOutputStream baos = new ByteArrayOutputStream();
		try {
			FileOutputStream fos = new FileOutputStream("test.rtf");
			rtfKit.write(baos, tp.getStyledDocument(), 0, tp.getStyledDocument().getLength());
			ObjectOutput ostrm = new ObjectOutputStream(fos);
    		ostrm.writeObject(baos.toString());
    		ostrm.flush();
    		PrintWriter out = new PrintWriter(new FileWriter("tst.rtf"));
    	    out.print(baos.toString());
    	    out.close();
		} 
		catch (IOException e1) {} 
		catch (BadLocationException e1) {}
//		System.out.println(baos.toString() + "\n********\n" + tt.rtf2Html(baos.toString()));
		
//    	final JFileChooser fc = new JFileChooser();
//    	FileView fw = new FileView() {};
//    	fc.setFileView(fw);
//    	fc.setAccessory(new ImagePreview(fc)); 
//    	int returnVal = fc.showOpenDialog(this);
//
//        if (returnVal == JFileChooser.APPROVE_OPTION) {
//            File file = fc.getSelectedFile();
//            try {
//				ImageIcon icon = new ImageIcon(file.getCanonicalPath());
//				tp.insertIcon(icon);
//			} catch (IOException e) {
//				// TODO Auto-generated catch block
//				e.printStackTrace();
//			}
//			
//        } else {
//        }
//
//    	ImageIcon icon = new ImageIcon();
//    	
//    	readStyledFile();
//    	writeRtfFile();
    	
//    	String str = "";
    	
//    	Style currentStyle = tp.getCharacterAttributes().getLogicalStyle();//.getInputAttributes();//.getCharacterAttributes();
//    	String str = (String)currentStyle.getAttribute(StyleConstants.NameAttribute);
//    	while (tp.getInputAttributes().getAttributeNames().hasMoreElements()) {
//    		Object type = (Object) tp.getInputAttributes().getAttributeNames().nextElement();
//    		System.out.println(type);
//		}
    	
//    	foreground=java.awt.Color[r=255,g=0,b=51] 
//    	italic=true 
//    	bold=true 
//    	size=36 
//    	underline=true 
//    	family=Times New Roman 
    	
    	
//    	ArrayList<String[]> sel = new ArrayList<String[]>();
//    	AttributeSet type = tp.getInputAttributes();
//    	sel.add(new String[]{"foreground",(String) type.getAttribute(StyleConstants.Foreground).toString()});
//    	sel.add(new String[]{"italic",(String) type.getAttribute(StyleConstants.Italic).toString()});
//    	sel.add(new String[]{"bold",(String) type.getAttribute(StyleConstants.Bold).toString()});
//    	sel.add(new String[]{"size",(String) type.getAttribute(StyleConstants.FontSize).toString()});
//    	sel.add(new String[]{"underline",(String) type.getAttribute(StyleConstants.Underline).toString()});
//    	sel.add(new String[]{"family",(String) type.getAttribute(StyleConstants.Family).toString()});
//    	sel.add(new String[]{"alignment",(String) type.getAttribute(StyleConstants.Alignment).toString()});
//    	Object[] list = sel.toArray();
//    	for (Object strings : list) {
//    		String[] element = (String[])strings;
//    		System.out.println(element[0] + " :: " +element[1]);
//		}
    	
    	
//    	System.out.println(sel.toString());//.getAttribute("font")
//    	System.out.println(tp.getInputAttributes());
//    	try {
//    		FileOutputStream fos = new FileOutputStream("test");
//    		rtfKit.write(fos, rtfDoc, 0, rtfDoc.getLength());
//    		
//			System.out.println(rtfDoc.getText(0, rtfDoc.getLength()));
//    		str =fos.toString();
//			System.out.println(fos.toString());
//			fos.flush();
//    		fos.close();
//		} catch (IOException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		} catch (BadLocationException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
    	return textPane.getText();
    }
    
    public final JTextPane getThisTextPane(){
    	return tp;
    }
    
    
    public void readStyledFile(){
	    FileDialog fileDialog = new FileDialog(new Frame());
	    fileDialog.setMode(FileDialog.LOAD);
	    fileDialog.setVisible(true);//.show();
	    
	    String file = fileDialog.getFile();
	    if (file == null) {
		return;
	    }
	    String directory = fileDialog.getDirectory();
	    System.out.println(file);
	    File f = new File(directory, file);
	    if (f.exists()) {
		try {
		    FileInputStream fin = new FileInputStream(f);
		    ObjectInputStream istrm = new ObjectInputStream(fin);
		    Document doc = (Document) istrm.readObject();
		    if(tp.getDocument() != null)
//			tp.getDocument().removeUndoableEditListener ((UndoableEditListener) undoAction);
		    tp.setDocument(doc);
//		    rtfDoc.addUndoableEditListener((UndoableEditListener) undoAction);
//		    resetUndoManager();
		    validate();
		} catch (IOException io) {
		    // should put in status panel
		    System.err.println("IOException: " + io.getMessage());
		} catch (ClassNotFoundException cnf) {
		    // should put in status panel
		    System.err.println("Class not found: " + cnf.getMessage());
		}
	    } else {
		// should put in status panel
		System.err.println("No such file: " + f);
	    }
    }
    public void writeStyledFile(){    
    	
    	final JFileChooser fc = new JFileChooser();
    	fc.setAcceptAllFileFilterUsed(false);
    	fc.addChoosableFileFilter(new StyledDocumentJarFilter());
    	fc.addChoosableFileFilter(new StyledDocumentZipFilter());
    	fc.addChoosableFileFilter(new RichTextFormatFilter());
    	fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
    	fc.setCurrentDirectory(new File(res.getCurrPath()));
    	fc.setAccessory(textHelp); 
    	
    	int returnVal = fc.showSaveDialog(Editor.this);
    	
        if (returnVal == JFileChooser.APPROVE_OPTION) {
        try{
        	String fileFilter = fc.getFileFilter().getDescription();
        	File file = fc.getSelectedFile();
        	String extension = Utils.getExtension(file);
        	
        	ByteArrayOutputStream baos = new ByteArrayOutputStream();
        	rtfKit.write(baos, tp.getStyledDocument(), 0, tp.getStyledDocument().getLength());
        	
        	if(fileFilter.startsWith("*.jar")){
    	        if (extension != null) {
    	            if (!extension.equals(Utils.jar)) {
    	                    file = new File(file.getCanonicalPath() + ".jar");
    	            }
    	            
    	        }else{
    	        	file = new File(file.getCanonicalPath() + ".jar");
    	        }
    	        JSDViewer jsd= new JSDViewer(tp.getDocument(), null);
	            jsd.createJAR(file.getCanonicalPath(),"jar");
	            
        	}else if(fileFilter.startsWith("*.zip")){
    	        if (extension != null) {
    	            if (!extension.equals(Utils.zip)) {
    	                    file = new File(file.getCanonicalPath() + ".zip");
    	            }
    	            
    	        }else{
    	        	file = new File(file.getCanonicalPath() + ".zip");
    	        }
    	        JSDViewer jsd= new JSDViewer(tp.getDocument(), null);
	            jsd.createJAR(file.getCanonicalPath(),"zip");
	            
        	}else if(fileFilter.startsWith("*.rtf")){
        		if (extension != null) {
    	            if (!extension.equals(Utils.rtf)) {
    	                    file = new File(file.getCanonicalPath() + ".rtf");
    	            }
    	        }else{
    	        	file = new File(file.getCanonicalPath() + ".rtf");
    	        }
        		PrintWriter out = new PrintWriter(new FileWriter(file.getCanonicalPath()));
        	    out.print(baos.toString());
        	    out.close();
        	}
        	
        	
        }catch(IOException io){}
        catch(BadLocationException bl){}
        }
    }
    
    public void insertImageToPane(){
    	final JFileChooser fc = new JFileChooser();
    	fc.setAcceptAllFileFilterUsed(false);
    	fc.addChoosableFileFilter(new ImageFilter());
    	fc.setAccessory(new ImagePreview(fc)); 
    	fc.setFileSelectionMode(JFileChooser.FILES_ONLY);

    	int returnVal = fc.showOpenDialog(Editor.this);
    	
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File file = fc.getSelectedFile();
            System.out.println(file);
            try {
				ImageIcon icon = new ImageIcon(file.getCanonicalPath());
				tp.insertIcon(icon);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
        }
    }
	
    
    // ***************************************
	// *** PRIVATE AND PROTECTED METHODS *****
	// ***************************************

	
	private void setToolBarEnabled(boolean isEnabled){
		// 
	}
	
	private JToolBar getToolBar(){
		
		JToolBar tbEditor = new JToolBar();
		{
			JSeparator js;
			
			JButton btnCustom01 = new JButton(res.propIcon) {
	        	private static final long serialVersionUID = 1L;
	            public float getAlignmentY() { return 0.5f; }
			};
			btnCustom01.setRequestFocusEnabled(false);
			btnCustom01.setToolTipText("erweiterte Einstellungen");
			btnCustom01.setMargin(new Insets(1,1,1,1));
			tbEditor.add(btnCustom01);
			btnCustom01.addActionListener(new ActionListener() {
	        	public void actionPerformed(ActionEvent evt) {
	        		fireButtonOptions(evt);
	        	}
	        });
			
			JButton btnSave = new JButton(res.saveIcon) {
	        	private static final long serialVersionUID = 1L;
	            public float getAlignmentY() { return 0.5f; }
			};
			btnSave.setRequestFocusEnabled(false);
			btnSave.setMargin(new Insets(1,1,1,1));
			tbEditor.add(btnSave);
			btnSave.addActionListener(new ActionListener() {
	        	public void actionPerformed(ActionEvent evt) {
	        		fireButtonSave(evt);
	        	}
	        });
			
			JButton btnDelete = new JButton(res.deleteIcon) {
	        	private static final long serialVersionUID = 1L;
	            public float getAlignmentY() { return 0.5f; }
			};
			btnDelete.setRequestFocusEnabled(false);
			btnDelete.setMargin(new Insets(1,1,1,1));
			tbEditor.add(btnDelete);
			btnDelete.addActionListener(new ActionListener() {
	        	public void actionPerformed(ActionEvent evt) {
	        		fireButtonDelete(evt);
	        	}
	        });
			
			JButton btnRefresh = new JButton(res.refreshIcon) {
	        	private static final long serialVersionUID = 1L;
	            public float getAlignmentY() { return 0.5f; }
			};
			btnRefresh.setRequestFocusEnabled(false);
			btnRefresh.setMargin(new Insets(1,1,1,1));
			tbEditor.add(btnRefresh);
			btnRefresh.addActionListener(new ActionListener() {
	        	public void actionPerformed(ActionEvent evt) {
	        		fireButtonRefresh(evt);
	        	}
	        });
			
			js = new JSeparator(SwingConstants.VERTICAL);
			tbEditor.add(js);
			
			JButton btnUndo = new JButton(res.undoIcon) {
	        	private static final long serialVersionUID = 1L;
	            public float getAlignmentY() { return 0.5f; }
			};
			btnUndo.setRequestFocusEnabled(false);
			btnUndo.setMargin(new Insets(1,1,1,1));
			tbEditor.add(btnUndo);
			btnUndo.addActionListener(new UndoAction());

			JButton btnRedo = new JButton(res.redoIcon) {
	        	private static final long serialVersionUID = 1L;
	            public float getAlignmentY() { return 0.5f; }
			};
			btnRedo.setRequestFocusEnabled(false);
			btnRedo.setMargin(new Insets(1,1,1,1));
			tbEditor.add(btnRedo);
			btnRedo.addActionListener(new RedoAction());

			js = new JSeparator(SwingConstants.VERTICAL);
			tbEditor.add(js);
			
			JButton btnBold = new JButton(res.boldIcon) {
	        	private static final long serialVersionUID = 1L;
	            public float getAlignmentY() { return 0.5f; }
			};
			btnBold.setRequestFocusEnabled(false);
			btnBold.setMargin(new Insets(1,1,1,1));
			tbEditor.add(btnBold);
			btnBold.addActionListener(new StyledEditorKit.BoldAction());

			JButton btnItalic = new JButton(res.italicIcon) {
	        	private static final long serialVersionUID = 1L;
	            public float getAlignmentY() { return 0.5f; }
			};
			btnItalic.setRequestFocusEnabled(false);
			btnItalic.setMargin(new Insets(1,1,1,1));
			tbEditor.add(btnItalic);
			btnItalic.addActionListener(new StyledEditorKit.ItalicAction());

			JButton btnUnderline = new JButton(res.underlineIcon) {
	        	private static final long serialVersionUID = 1L;
	            public float getAlignmentY() { return 0.5f; }
			};
			btnUnderline.setRequestFocusEnabled(false);
			btnUnderline.setMargin(new Insets(1,1,1,1));
			tbEditor.add(btnUnderline);
			btnUnderline.addActionListener(new StyledEditorKit.UnderlineAction());

			JButton btnColor = new JButton(res.colorIcon) {
	        	private static final long serialVersionUID = 1L;
	            public float getAlignmentY() { return 0.5f; }
			};
			btnColor.setRequestFocusEnabled(false);
			btnColor.setMargin(new Insets(1,1,1,1));
			tbEditor.add(btnColor);
			btnColor.addActionListener(new ActionListener() {
	        	public void actionPerformed(ActionEvent evt) {
	        		Color newColor = JColorChooser.showDialog(
	        			new JFrame(),"Choose Background Color",Color.black);
	        		Action colorAction = new StyledEditorKit.ForegroundAction("color", newColor);
	        		colorAction.actionPerformed(null);
	        	}
	        });

			js = new JSeparator(SwingConstants.VERTICAL);
			tbEditor.add(js);
			
			JButton btnLeft = new JButton(res.leftIcon) {
	        	private static final long serialVersionUID = 1L;
	            public float getAlignmentY() { return 0.5f; }
			};
			btnLeft.setRequestFocusEnabled(false);
			btnLeft.setMargin(new Insets(1,1,1,1));
			tbEditor.add(btnLeft);
			btnLeft.addActionListener(
					new StyledEditorKit.AlignmentAction("left", StyleConstants.ALIGN_LEFT));

			JButton btnCenter = new JButton(res.centerIcon) {
	        	private static final long serialVersionUID = 1L;
	            public float getAlignmentY() { return 0.5f; }
			};
			btnCenter.setRequestFocusEnabled(false);
			btnCenter.setMargin(new Insets(1,1,1,1));
			tbEditor.add(btnCenter);
			btnCenter.addActionListener(
					new StyledEditorKit.AlignmentAction("left", StyleConstants.ALIGN_CENTER));

			JButton btnFill = new JButton(res.fillIcon) {
	        	private static final long serialVersionUID = 1L;
	            public float getAlignmentY() { return 0.5f; }
			};
			btnFill.setRequestFocusEnabled(false);
			btnFill.setMargin(new Insets(1,1,1,1));
			tbEditor.add(btnFill);
			btnFill.addActionListener(
					new StyledEditorKit.AlignmentAction("left", StyleConstants.ALIGN_JUSTIFIED));

			JButton btnRight = new JButton(res.rightIcon) {
	        	private static final long serialVersionUID = 1L;
	            public float getAlignmentY() { return 0.5f; }
			};
			btnRight.setRequestFocusEnabled(false);
			btnRight.setMargin(new Insets(1,1,1,1));
			tbEditor.add(btnRight);
			btnRight.addActionListener(
					new StyledEditorKit.AlignmentAction("left", StyleConstants.ALIGN_RIGHT));

			js = new JSeparator(SwingConstants.VERTICAL);
			tbEditor.add(js);
			
			JButton btnSerif = new JButton(res.serifIcon) {
	        	private static final long serialVersionUID = 1L;
	            public float getAlignmentY() { return 0.5f; }
			};
			btnSerif.setRequestFocusEnabled(false);
			btnSerif.setMargin(new Insets(1,1,1,1));
			tbEditor.add(btnSerif);
			btnSerif.addActionListener(
					new StyledEditorKit.FontFamilyAction("font","Times New Roman"));

			JButton btnSanserif = new JButton(res.sanSerifIcon) {
	        	private static final long serialVersionUID = 1L;
	            public float getAlignmentY() { return 0.5f; }
			};
			btnSanserif.setRequestFocusEnabled(false);
			btnSanserif.setMargin(new Insets(1,1,1,1));
			tbEditor.add(btnSanserif);
			btnSanserif.addActionListener(
					new StyledEditorKit.FontFamilyAction("font","Verdana"));
			
			JComboBox cbFontSize = new JComboBox(
				new String[] {"10","12","14","16","18","24","36","48"});
			tbEditor.add(cbFontSize);
			cbFontSize.setSelectedItem("12");
			cbFontSize.addActionListener(new ActionListener() {
				
				@Override
				public void actionPerformed(ActionEvent e) {
					JComboBox comboBox = (JComboBox)e.getSource();
					int fontSize = Integer.parseInt( comboBox.getSelectedItem().toString() );
					Action fontAction = new StyledEditorKit.FontSizeAction("size", fontSize);
					fontAction.actionPerformed(null);
					
				}
			});
			
			final JToggleButton btnToogle = new JToggleButton("SRC");
			tbEditor.add(btnToogle);
			btnToogle.addActionListener(new ActionListener() {
				
				@Override
				public void actionPerformed(ActionEvent e) {
					String content;
					if (btnToogle.getModel().isSelected()){
						ByteArrayOutputStream baos = new ByteArrayOutputStream();
						try {
							rtfKit.write(baos, rtfDoc, 0, rtfDoc.getLength());
						} 
						catch (IOException e1) {} 
						catch (BadLocationException e1) {}
						System.out.println(baos.toString());
						textPane.setText(tp.getText());
						sp.setViewportView(textHolder2);
					}else{
						try {
							content = document.getText(0,document.getLength());
							System.out.println(textPane.getText());
							System.out.println(content);
							tp.setText(textPane.getText());
						} catch (BadLocationException e1) {}
						sp.setViewportView(textHolder1);
					}
					
					
				}
			});

		}
		tbEditor.setFloatable(false);
		tbEditor.setOpaque(false);
		tbEditor.setOrientation(JToolBar.HORIZONTAL);
		
		return tbEditor;
	}
	
	private void insertHtmlText(String content){
//		try {
//			int pos = tp.getCaretPosition();
//			rtfKit.insertHTML(rtfDoc, pos, content, 0, 0, null);
//		} catch (BadLocationException e) {
//			e.printStackTrace();
//		} catch (IOException e) {
//			e.printStackTrace();
//		}

	}
	
	private static void changeClipboard(){
//		String clip = getClipboard();
//		if(clip != null)setClipboard(clip);
	}
	
	// If a string is on the system clipboard, this method returns it;
    // otherwise it returns null.
    public static String getClipboard() {
        Transferable t = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null);
    
        try {
            if (t != null && t.isDataFlavorSupported(DataFlavor.stringFlavor)) {
            	BufferedReader f;
            	String line = "";
            	String text = "";
            	     try {
            	       f = new BufferedReader(
            	    		   DataFlavor.getTextPlainUnicodeFlavor().getReaderForText(t));
            	       while ((line = f.readLine()) != null) {
            	         text += "\n" + line ;
            	       }
            	       f.close();
            	     } catch (IOException e) {
            	       
            	     }
                return text;
            }
        } catch (UnsupportedFlavorException e) {
        } catch (Exception e) {
        }
        return null;
    }
    
    // This method writes a string to the system clipboard.
    // otherwise it returns null.
    public static void setClipboard(String str) {
        StringSelection ss = new StringSelection(str);
        Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss, null);
    }

	
    private void createStyles(StyledDocument doc) {
    	Style root = doc.getStyle("default");
        Style baseStyle = doc.addStyle("base", root);
        StyleConstants.setFontFamily(baseStyle, "Verdana");//"Lucida Sans Unicode"
        StyleConstants.setFontSize(baseStyle, 12);
 
        tp.setLogicalStyle(baseStyle);
    }
 
    private void setContent(StyledDocument doc, String text) {
        try {
            doc.insertString(0, text, doc.getStyle("base"));
        } catch(BadLocationException e) {
            //System.out.printf("bad location error: %s%n", e.getMessage());
        }
    }



	private void createPopUp(final JTextPane tp){
		actions=createActionTable(tp);
		
	    //...where the GUI is constructed:
	    //Create the popup menu.
	    popup = new JPopupMenu();
	    
	    menuItem = new JMenuItem("alles markieren");
	    menuItem.setAccelerator(KeyStroke.getKeyStroke(
	            KeyEvent.VK_A, ActionEvent.CTRL_MASK));
	    menuItem.addActionListener(getActionByName(DefaultEditorKit.selectAllAction));
	    popup.add(menuItem);
	    
	    popup.addSeparator();
	    
	    menuItem = new JMenuItem("ausschneiden");
	    menuItem.setAccelerator(KeyStroke.getKeyStroke(
	            KeyEvent.VK_X, ActionEvent.CTRL_MASK));
	    menuItem.addActionListener(getActionByName(DefaultEditorKit.cutAction));
	    popup.add(menuItem);
	    
	    menuItem = new JMenuItem("kopieren");
	    menuItem.setAccelerator(KeyStroke.getKeyStroke(
	            KeyEvent.VK_C, ActionEvent.CTRL_MASK));
	    menuItem.addActionListener(getActionByName(DefaultEditorKit.copyAction));
	    popup.add(menuItem);
	    
	    menuItem = new JMenuItem("einfuegen");
	    menuItem.setAccelerator(KeyStroke.getKeyStroke(
	            KeyEvent.VK_V, ActionEvent.CTRL_MASK));
	    menuItem.addActionListener(getActionByName(DefaultEditorKit.pasteAction));
//	    		new ActionListener() {
//        	public void actionPerformed(ActionEvent evt) {
//        		changeClipboard();
//				Action pasteAction = getActionByName(DefaultEditorKit.pasteAction);
//				pasteAction.actionPerformed(null);
//        		setTabs(tp, TAB_SIZE);
//	        }
//	    });		    
	    popup.add(menuItem);
	    
	    popup.addSeparator();
	    
	    submenu = new JMenu("neue Ueberschrift");
	    {
		    menuItem = new JMenuItem("H1");
		    menuItem.setAccelerator(KeyStroke.getKeyStroke(
		            KeyEvent.VK_1, ActionEvent.ALT_MASK));
//		    menuItem.addActionListener(new ActionListener() {
//	        	public void actionPerformed(ActionEvent evt) {
//	        		insertHtmlText("<h1>Ueberschrift H1</h1>");
//	        		setTabs(tp, TAB_SIZE);
//	        	}
//	        });		    
		    submenu.add(menuItem);
	
		    menuItem = new JMenuItem("H2");
		    menuItem.setAccelerator(KeyStroke.getKeyStroke(
		            KeyEvent.VK_2, ActionEvent.ALT_MASK));
//		    menuItem.addActionListener(new ActionListener() {
//	        	public void actionPerformed(ActionEvent evt) {
//	        		insertHtmlText("<h2>Ueberschrift H2</h2>");
//					setTabs(tp, TAB_SIZE);
//	        	}
//	        });		    
		    submenu.add(menuItem);
		    menuItem = new JMenuItem("H3");
		    menuItem.setAccelerator(KeyStroke.getKeyStroke(
		            KeyEvent.VK_3, ActionEvent.ALT_MASK));
//		    menuItem.addActionListener(new ActionListener() {
//	        	public void actionPerformed(ActionEvent evt) {
//	        		insertHtmlText("<h3>Ueberschrift H3</h3>");
//					setTabs(tp, TAB_SIZE);
//	        	}
//	        });		    
		    submenu.add(menuItem);
		    menuItem = new JMenuItem("H4");
		    menuItem.setAccelerator(KeyStroke.getKeyStroke(
		            KeyEvent.VK_4, ActionEvent.ALT_MASK));
//		    menuItem.addActionListener(new ActionListener() {
//	        	public void actionPerformed(ActionEvent evt) {
//	        		insertHtmlText("<h4>Ueberschrift H4</h4>");
//					setTabs(tp, TAB_SIZE);
//	        	}
//	        });		    
		    submenu.add(menuItem);
	    }
	    popup.add(submenu);

	    
	    menuItem = new JMenuItem("neuer Absatz");
	    menuItem.setAccelerator(KeyStroke.getKeyStroke(
	            KeyEvent.VK_ENTER, ActionEvent.CTRL_MASK));
//	    menuItem.addActionListener(new ActionListener() {
//        	public void actionPerformed(ActionEvent evt) {
//        		String[] oldText = tp.getText().split("</body>");
//    			String newText = oldText[0] + "\n<pre></pre>\n</body>" + oldText[1];
//				tp.setText(newText);
//				setTabs(tp, TAB_SIZE);
//        	}
//        });
	    popup.add(menuItem);
	    
	    menuItem = new JMenuItem("neue CODE-Umgebung");
	    menuItem.setAccelerator(KeyStroke.getKeyStroke(
	            KeyEvent.VK_C, ActionEvent.ALT_MASK));
//	    menuItem.addActionListener(new ActionListener() {
//        	public void actionPerformed(ActionEvent evt) {
//        		insertHtmlText("<pre id=\"inote\" border=\"1\">&lt;CODE&gt;\n\n&lt;/CODE&gt;</pre>");
//				setTabs(tp, TAB_SIZE);
//        	}
//        });
	    popup.add(menuItem);

	    
	    popup.addSeparator();
	    
	    menuItem = new JMenuItem("erweiterte Einstellungen");
	    menuItem.setAccelerator(KeyStroke.getKeyStroke(
	            KeyEvent.VK_E, ActionEvent.ALT_MASK));
	    menuItem.addActionListener(new ActionListener() {
        	public void actionPerformed(ActionEvent evt) {
        		fireButtonOptions(evt);
        	}
        });
	    popup.add(menuItem);
	    
	}
	
	private KeyListener getEditorKeyListener(){
		KeyListener keyListener = new KeyListener() {
			
			@Override
			public void keyTyped(KeyEvent e) {}
			
			@Override
			public void keyReleased(KeyEvent e) {}
			
			@Override
			public void keyPressed(KeyEvent e) {
				if(KeyEvent.VK_ENTER == e.getKeyCode()){
//					e.consume();
//					if (e.isControlDown()){
//						String[] oldText = tp.getText().split("</body>");
//		    			String newText = oldText[0] + "\n<pre></pre>\n</body>" + oldText[1];
//						tp.setText(newText);
//						setTabs(tp, TAB_SIZE);
//					}
//					else {
//						int pos = tp.getCaretPosition();
//						try {
//							tp.getDocument().insertString(pos, "%%BR%%", tp.getCharacterAttributes());
//							tp.setText(tp.getText().replace("%%BR%%", "<br>"));
//							tp.setCaretPosition(pos + 1);
//						} catch (BadLocationException e1) {
//							e1.printStackTrace();
//						}
//					}
				}
				else if(e.isAltDown()){
					if(KeyEvent.VK_C == e.getKeyCode()){
////						insertHtmlText("<pre border=\"1\">&lt;CODE&gt;\n\n&lt;/CODE&gt;</pre>");
//						String[] oldText = tp.getText().split("</body>");
//		    			String newText = oldText[0] + "\n<pre id=\"inote\" border=\"1\">&lt;CODE&gt;\n\n&lt;/CODE&gt;</pre>\n</body>" + oldText[1];
//						tp.setText(newText);
						setTabs(tp, TAB_SIZE);
					}
					else if(KeyEvent.VK_E == e.getKeyCode()){
						fireButtonOptions(null);
					}
					else if(KeyEvent.VK_1 == e.getKeyCode()){
//						String[] oldText = tp.getText().split("</body>");
//		    			String newText = oldText[0] + "\n<h1>Ueberschrift H1</h1>\n</body>" + oldText[1];
//						tp.setText(newText);
						setTabs(tp, TAB_SIZE);
					}
					else if(KeyEvent.VK_2 == e.getKeyCode()){
//						String[] oldText = tp.getText().split("</body>");
//		    			String newText = oldText[0] + "\n<h2>Ueberschrift H2</h2>\n</body>" + oldText[1];
//						tp.setText(newText);
						setTabs(tp, TAB_SIZE);
					}
					else if(KeyEvent.VK_3 == e.getKeyCode()){
//						String[] oldText = tp.getText().split("</body>");
//		    			String newText = oldText[0] + "\n<h3>Ueberschrift H3</h3>\n</body>" + oldText[1];
//						tp.setText(newText);
						setTabs(tp, TAB_SIZE);
					}
					else if(KeyEvent.VK_4 == e.getKeyCode()){
//						String[] oldText = tp.getText().split("</body>");
//		    			String newText = oldText[0] + "\n<h4>Ueberschrift H4</h4>\n</body>" + oldText[1];
//						tp.setText(newText);
						setTabs(tp, TAB_SIZE);
					}
				}
				else if(e.isControlDown()){
					if (KeyEvent.VK_V == e.getKeyCode()){
//						e.consume();
//						changeClipboard();
//						Action pasteAction = getActionByName(DefaultEditorKit.pasteAction);
//						pasteAction.actionPerformed(null);
					}
				}
			}

		};
		return keyListener;
	}
	
	private void setTabs( JTextPane textPane, int charactersPerTab)
	{
//		FontMetrics fm = textPane.getFontMetrics( textPane.getFont() );
//		int charWidth = fm.charWidth( 'w' );
//		int tabWidth = charWidth * charactersPerTab;
// 
//		TabStop[] tabs = new TabStop[10];
// 
//		for (int j = 0; j < tabs.length; j++)
//		{
//			int tab = j + 1;
//			tabs[j] = new TabStop( tab * tabWidth );
//		}
// 
//		TabSet tabSet = new TabSet(tabs);
//		SimpleAttributeSet attributes = new SimpleAttributeSet();
//		StyleConstants.setTabSet(attributes, tabSet);
//		int length = textPane.getDocument().getLength();
//		textPane.getStyledDocument().setParagraphAttributes(0, length, attributes, false);
	}

	
	//The following two methods allow us to find an
    //action provided by the editor rtfKit by its name.
    private HashMap<Object, Action> createActionTable(JTextComponent textComponent) {
        HashMap<Object, Action> actions = new HashMap<Object, Action>();
        Action[] actionsArray = textComponent.getActions();
        for (int i = 0; i < actionsArray.length; i++) {
            Action a = actionsArray[i];
            actions.put(a.getValue(Action.NAME), a);
        }
        return actions;
    }
	
	private Action getActionByName(String name) {
        return actions.get(name);
    }

	
	
	
    // ********************************************
	// *** INNER CLASSES FOR EDITOR ***************
	// ********************************************

	protected class MyUndoableEditListener implements UndoableEditListener {
		public void undoableEditHappened(UndoableEditEvent e) {
			// Remember the edit and update the menus.
			try {
				undo.addEdit(e.getEdit());
				undoAction.updateUndoState();
				redoAction.updateRedoState();
			} 
			catch (Exception ex) {}
		}
	}
	
    class UndoAction extends AbstractAction {
    	
    	private static final long serialVersionUID = 1L;
    	
        public UndoAction() {
            super("Undo");
            setEnabled(false);
        }

        public void actionPerformed(ActionEvent e) {
            try {
                undo.undo();
                updateUndoState();
                redoAction.updateRedoState();
            } 
            catch (Exception ex) {}
        }

        protected void updateUndoState() {
            if (undo.canUndo()) {
                setEnabled(true);
                putValue(Action.NAME, undo.getUndoPresentationName());
            } else {
                setEnabled(false);
                putValue(Action.NAME, "Undo");
            }
        }
    }

    class RedoAction extends AbstractAction {

    	private static final long serialVersionUID = 1L;

		public RedoAction() {
            super("Redo");
            setEnabled(false);
        }

        public void actionPerformed(ActionEvent e) {
            try {
                undo.redo();
                updateRedoState();
                undoAction.updateUndoState();
            }
            catch (Exception ex) {}
        }

        protected void updateRedoState() {
            if (undo.canRedo()) {
                setEnabled(true);
                putValue(Action.NAME, undo.getRedoPresentationName());
            } else {
                setEnabled(false);
                putValue(Action.NAME, "Redo");
            }
        }
    }
    
	class PopupListener extends MouseAdapter {
	    public void mousePressed(MouseEvent e) {
	        showPopup(e);
	    }

	    public void mouseReleased(MouseEvent e) {
	        showPopup(e);
	    }

	    private void showPopup(MouseEvent e) {
	        if (e.isPopupTrigger()) {
	            popup.show(e.getComponent(),
	                       e.getX(), e.getY());
	        }
	    }
	}
	
	class TextTransformer {
		private JEditorPane editor = new JEditorPane();
		private RTFEditorKit rtfKit = new RTFEditorKit();
		private HTMLEditorKit htmlKit = new HTMLEditorKit();
		private Document htmldoc;
		private Document rtfdoc;
		private StringReader reader;

		public String rtf2Text(String input){
			
			if (!input.startsWith("{\\rtf1"))return input;

			reader = new StringReader(input);
			editor.setEditorKit(rtfKit);
			rtfdoc = editor.getDocument();

			try {
				rtfKit.read(reader, rtfdoc, 0);
				return rtfdoc.getText(0, rtfdoc.getLength());
			} catch (IOException io) {
				return "";
			} catch (BadLocationException be) {
				return "";
			}
		}

		public String html2Text(String input){
			
			reader = new StringReader(input);
			editor.setEditorKit(htmlKit);
			htmldoc = editor.getDocument();

			try {
				htmlKit.read(reader, htmldoc, 0);
				return htmldoc.getText(0, htmldoc.getLength());
			} catch (IOException io) {
				return "";
			} catch (BadLocationException be) {
				return "";
			}
		}

		public String rtf2Html(String input){
			
			if (!input.startsWith("{\\rtf1"))return string2Html(input);

			reader = new StringReader(input);
			editor.setEditorKit(rtfKit);
			rtfdoc = editor.getDocument();

			try {
				rtfKit.read(reader, rtfdoc, 0);
				ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
				htmlKit.write(byteArrayOutputStream, rtfdoc, 0, rtfdoc.getLength());
				return byteArrayOutputStream.toString();
			} catch (IOException io) {
				return "";
			} catch (BadLocationException be) {
				return "";
			}
		}

		public String html2Rtf(String input){
			
			reader = new StringReader(input);
			editor.setEditorKit(htmlKit);
			htmldoc = editor.getDocument();

			try {
				htmlKit.read(reader, htmldoc, 0);
				ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
				rtfKit.write(byteArrayOutputStream, htmldoc, 0, htmldoc.getLength());
				return byteArrayOutputStream.toString();
			} catch (IOException io) {
				return "";
			} catch (BadLocationException be) {
				return "";
			}
		}

		public String string2Html(String input){
			return "<span>" + input + "</span>";
		}

	}// END CLASS TEXTTRANSFORMER
	
	class ImagePreview extends JComponent implements PropertyChangeListener {
		ImageIcon thumbnail = null;
		File file = null;

		public ImagePreview(JFileChooser fc) {
			setPreferredSize(new Dimension(100, 50));
			fc.addPropertyChangeListener(this);
		}

		public void loadImage() {
			if (file == null) {
				thumbnail = null;
				return;
			}

			// Don't use createImageIcon (which is a wrapper for getResource)
			// because the image we're trying to load is probably not one
			// of this program's own resources.
			ImageIcon tmpIcon = new ImageIcon(file.getPath());
			if (tmpIcon != null) {
				if (tmpIcon.getIconWidth() > 90) {
					thumbnail = new ImageIcon(tmpIcon.getImage()
							.getScaledInstance(90, -1, Image.SCALE_DEFAULT));
				} else { // no need to miniaturize
					thumbnail = tmpIcon;
				}
			}
		}

		public void propertyChange(PropertyChangeEvent e) {
			boolean update = false;
			String prop = e.getPropertyName();

			// If the directory changed, don't show an image.
			if (JFileChooser.DIRECTORY_CHANGED_PROPERTY.equals(prop)) {
				file = null;
				update = true;

				// If a file became selected, find out which one.
			} else if (JFileChooser.SELECTED_FILE_CHANGED_PROPERTY.equals(prop)) {
				file = (File) e.getNewValue();
				update = true;
			}

			// Update the preview accordingly.
			if (update) {
				thumbnail = null;
				if (isShowing()) {
					loadImage();
					repaint();
				}
			}
		}

		protected void paintComponent(Graphics g) {
			if (thumbnail == null) {
				loadImage();
			}
			if (thumbnail != null) {
				int x = getWidth() / 2 - thumbnail.getIconWidth() / 2;
				int y = getHeight() / 2 - thumbnail.getIconHeight() / 2;

				if (y < 0) {
					y = 0;
				}

				if (x < 5) {
					x = 5;
				}
				thumbnail.paintIcon(this, g, x, y);
			}
		}
	}
	
	class StyledDocumentJarFilter extends FileFilter {

	    //Accept all directories and all gif, jpg, tiff, or png files.
	    public boolean accept(File f) {
	        if (f.isDirectory()) {
	            return true;
	        }

	        String extension = Utils.getExtension(f);
	        if (extension != null) {
	            if (extension.equals(Utils.jar)) {
	                    return true;
	            } else {
	                return false;
	            }
	        }

	        return false;
	    }

	    //The description of this filter
	    public String getDescription() {
	        return "*.jar - Java Styled Document (mit Viewer)";
	    }
	}
	
	class StyledDocumentZipFilter extends FileFilter {

	    //Accept all directories and all gif, jpg, tiff, or png files.
	    public boolean accept(File f) {
	        if (f.isDirectory()) {
	            return true;
	        }

	        String extension = Utils.getExtension(f);
	        if (extension != null) {
	            if (extension.equals(Utils.zip)) {
	                    return true;
	            } else {
	                return false;
	            }
	        }

	        return false;
	    }

	    //The description of this filter
	    public String getDescription() {
	        return "*.zip - Java Styled Document";
	    }
	}

	class RichTextFormatFilter extends FileFilter {

	    //Accept all directories and all gif, jpg, tiff, or png files.
	    public boolean accept(File f) {
	        if (f.isDirectory()) {
	            return true;
	        }

	        String extension = Utils.getExtension(f);
	        if (extension != null) {
	            if (extension.equals(Utils.rtf)) {
	                    return true;
	            } else {
	                return false;
	            }
	        }

	        return false;
	    }

	    //The description of this filter
	    public String getDescription() {
	        return "*.rtf - Rich Text Format";
	    }
	}
	
	class ImageFilter extends FileFilter {

	    //Accept all directories and all gif, jpg, tiff, or png files.
	    public boolean accept(File f) {
	        if (f.isDirectory()) {
	            return true;
	        }

	        String extension = Utils.getExtension(f);
	        if (extension != null) {
	            if (extension.equals(Utils.tiff) ||
	                extension.equals(Utils.tif) ||
	                extension.equals(Utils.gif) ||
	                extension.equals(Utils.jpeg) ||
	                extension.equals(Utils.jpg) ||
	                extension.equals(Utils.png)) {
	                    return true;
	            } else {
	                return false;
	            }
	        }

	        return false;
	    }

	    //The description of this filter
	    public String getDescription() {
	        return "Bilddateien";
	    }
	}
	
	static class Utils {
	    public final static String jpeg = "jpeg";
	    public final static String jpg = "jpg";
	    public final static String gif = "gif";
	    public final static String tiff = "tiff";
	    public final static String tif = "tif";
	    public final static String png = "png";
	    public final static String jsd = "jsd";
	    public final static String rtf = "rtf";
	    public final static String jar = "jar";
	    public final static String zip = "zip";

	    /*
	     * Get the extension of a file.
	     */
	    public static String getExtension(File f) {
	        String ext = null;
	        String s = f.getName();
	        int i = s.lastIndexOf('.');

	        if (i > 0 &&  i < s.length() - 1) {
	            ext = s.substring(i+1).toLowerCase();
	        }
	        return ext;
	    }

	    /** Returns an ImageIcon, or null if the path was invalid. */
	    protected static ImageIcon createImageIcon(String path) {
	        java.net.URL imgURL = Utils.class.getResource(path);
	        if (imgURL != null) {
	            return new ImageIcon(imgURL);
	        } else {
	            System.err.println("Couldn't find file: " + path);
	            return null;
	        }
	    }
	}


}// END CLASS IEDITOR
